package com.yricky.memoria.ui.component

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.res.Configuration
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.documentfile.provider.DocumentFile
import com.yricky.memoria.R
import com.yricky.memoria.data.SubjectModel
import com.yricky.memoria.data.WorkSpaceModel
import com.yricky.memoria.data.pojo.PdfQuery
import com.yricky.memoria.data.pojo.SectionQuery
import com.yricky.memoria.ui.component.common.HorizontalList
import com.yricky.memoria.ui.component.common.HorizontalPdfList
import com.yricky.memoria.ui.component.common.MenuItems
import com.yricky.memoria.ui.dialog.showConfirmDialog
import com.yricky.memoria.ui.dialog.showGetStrDialog
import com.yricky.memoria.ui.theme.ThemeInst
import com.yricky.memoria.ui.theme.drawerShape
import com.yricky.memoria.utils.*

/**
 * @author Yricky
 * @date 2021/11/21
 */
@Composable
fun Context.MainActivityContent(viewModel: MainActivityContentViewModel){
    ThemeInst.Material {
        // A surface container using the 'background' color from the theme
        if(resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE){
            MainActivityContentPadH(viewModel)
        }else {
            MainActivityContentPadV(viewModel)
        }

    }
}

@Composable
private fun MainActivityContentPadH(viewModel: MainActivityContentViewModel){
    Scaffold(
        floatingActionButton = { AddSectionFab(viewModel = viewModel) },
        content = {
            Row(
                Modifier
                    .fillMaxSize()
                    .padding(it)) {
                Drawer(viewModel)
                MainList(viewModel)
            }
    })

}

@Composable
private fun MainActivityContentPadV(viewModel: MainActivityContentViewModel){
    Column(Modifier.fillMaxSize()) {
        viewModel.scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Open))
        viewModel.scope = rememberCoroutineScope()

        Scaffold(
            scaffoldState = viewModel.scaffoldState,
            floatingActionButton = { AddSectionFab(viewModel = viewModel) },
            drawerContent = { Drawer(viewModel) },
            drawerShape = drawerShape,
            content = { MainList(viewModel) }
        )
    }
}

@OptIn(ExperimentalAnimationApi::class, ExperimentalFoundationApi::class)
@Composable
private fun Drawer(viewModel: MainActivityContentViewModel){
    val viewState by viewModel.viewState.collectAsState()
    val context = LocalContext.current
    Surface(
        shape = drawerShape,
        elevation = 4.dp
    ) {
        Column(
            Modifier
                .width(300.dp)
                .background(MaterialTheme.colors.background)
                .fillMaxHeight(),
        ) {
            Row(
                Modifier
                    .wrapContentHeight()
                    .fillMaxWidth()
                    .padding(16.dp, 8.dp),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text(
                    modifier = Modifier.weight(1f),
                    text = RStr.from(R.string.subject),
                    fontSize = 20.sp
                )
                Icon(
                    modifier = Modifier.clickable {
                        showGetStrDialog(context,RStr.stub("输入专题名"),""){ newSubjectName ->
                            if(newSubjectName != ""){   // 空字符表示对话框点击了取消
                                viewModel.onAction(MainActivityContentViewModel.Action.AddSubject(newSubjectName))
                            }
                        }
                    },
                    imageVector = Icons.Rounded.Add,
                    contentDescription = RStr.stub("")
                )
            }


            LazyColumn{
                viewState.subjectList.forEach{
                    item {
                        val expandState = remember {
                            mutableStateOf(false)
                        }

                        Row(
                            modifier = Modifier
                                .combinedClickable(
                                    onClick = {
                                        viewModel.onAction(
                                            MainActivityContentViewModel.Action.ToggleTagFold(
                                                it.first,
                                                viewState.tagFoldStat[it.first] == false
                                            )
                                        )
                                    },
                                    onLongClick = {
                                        // it.first==""时为全部笔记栏，不显示标签相关操作的DropDown
                                        expandState.value = it.first != ""
                                    }
                                )
                                .padding(8.dp)
                                .fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ){
                            Icon(
                                modifier = Modifier.size(24.dp).padding(0.dp,2.dp),
                                imageVector = ImageVector.vectorResource(
                                    id = if(it.first == "") R.drawable.ic_round_all_24 else R.drawable.ic_round_tag_24
                                ),
                                contentDescription = "",
                            )
                            Text(
                                modifier = Modifier
                                    .padding(8.dp, 0.dp)
                                    .weight(1f),
                                text = if(it.first == "") RStr.from(R.string.all) else it.first,
                                fontSize = 18.sp,
                                fontWeight = FontWeight.SemiBold,
                            )

                            if(viewState.tagFoldStat[it.first] == false){
                                Icon(
                                    imageVector = Icons.Rounded.ArrowDropDown,
                                    contentDescription = "",
                                )
                            }

                            DropdownMenu(
                                modifier = Modifier
                                    .wrapContentWidth()
                                    .wrapContentHeight()
                                    .padding(vertical = 0.dp)
                                    .align(Alignment.Bottom),
                                expanded = expandState.value,
                                onDismissRequest = {
                                    expandState.value = false
                                },
                                offset = DpOffset(64.dp, 0.dp),
                            ) {
                                MenuItems.Rename(
                                    state = expandState,
                                    callback = {
                                        showGetStrDialog(context, RStr.stub("输入新标签名"), it.first) { newTagName ->
                                            viewModel.renameTag(it.first, newTagName)
                                        }
                                    }
                                )
                                MenuItems.Delete(
                                    state = expandState,
                                    callback = {
                                        showConfirmDialog(context, "确认要删除标签 ${it.first} 吗", "你的专题仍会保留") {
                                            viewModel.delTag(it.first)
                                        }
                                    }
                                )
                            }
                        }

                    }
                    items(it.second){ subject->
                        AnimatedVisibility(visible = viewState.tagFoldStat[it.first] == true) {
                            SubjectItem(viewModel = viewModel, subject = subject, belongedTag = it.first){
                                viewModel.setFocusedSubject(subject)
                                viewModel.closeDrawer()
                            }
                        }
                    }
                }
                item {
                    Spacer(modifier = Modifier.height(120.dp))
                }
            }

        }
    }

}

@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun AddSectionFab(viewModel: MainActivityContentViewModel){
    val focusedSubject by viewModel.focusedSubject.observeAsState()
    val context = LocalContext.current
    var isShow:Boolean by remember {
        mutableStateOf(false)
    }
    focusedSubject?.let{
        Column {
            AnimatedVisibility(visible = isShow) {
                val launcher = rememberLauncherForActivityResult(
                    ActivityResultContracts.OpenDocument()) {
                    it?.let{ uri->
                        context.contentResolver.openInputStream(uri)?.let{
                            viewModel.importPdf(
                                DocumentFile.fromSingleUri(context, uri)?.name?:"${System.currentTimeMillis()}",
                                it)
                        }
                    }
                }
                FloatingActionButton(
                    onClick = {
                        launcher.launch(arrayOf("application/pdf"))
                    }) {
                    Icon(imageVector = ImageVector.vectorResource(id = R.drawable.ic_round_pdf_24)
                        , contentDescription = "")
                }
            }
            AnimatedVisibility(visible = isShow) {
                FloatingActionButton(
                    modifier = Modifier.padding(0.dp,8.dp),
                    onClick = { showGetStrDialog(context,RStr.stub("输入章节名")){ secName ->
                        focusedSubject?.addSection(secName)
                        viewModel.onAction(MainActivityContentViewModel.Action.QuerySections)
                    } }) {
                    Icon(imageVector = ImageVector.vectorResource(id = R.drawable.ic_round_section_24)
                        , contentDescription = "")
                }
            }


            FloatingActionButton(onClick = { isShow = !isShow }) {
                Icon(imageVector = if(isShow) Icons.Rounded.ArrowDropDown else Icons.Rounded.Add, contentDescription = "")
            }
        }

    }

}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun SubjectItem(
    viewModel: MainActivityContentViewModel,
    subject: WorkSpaceModel.SubjectMetaData,
    belongedTag: String,    // 该项为""表示该笔记项在全部笔记一栏中，否则表示在对应的标签栏中
    onClick:()->Unit = {}
){
    val context = LocalContext.current
    val focusedSubject by viewModel.focusedSubject.observeAsState()
    val expandState = remember {
        mutableStateOf(false)
    }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .combinedClickable(
                onClick = onClick,
                onLongClick = {
                    expandState.value = true
                }
            )
            .padding(24.dp, 8.dp, 8.dp, 8.dp)
    ) {
        Icon(
            imageVector = ImageVector.vectorResource(R.drawable.ic_round_subject_24),
            contentDescription = "",
            tint =
                if(focusedSubject?.uid == subject.uid)
                    MaterialTheme.colors.primary
                else
                    LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
        )
        Text(
            text = subject.name,
            maxLines = 2,
            overflow = TextOverflow.Ellipsis,
            modifier = Modifier
                .padding(6.dp, 0.dp)
        )
        Spacer(modifier = Modifier.weight(1f))
        if(focusedSubject?.uid == subject.uid){
            Icon(
                imageVector = ImageVector.vectorResource(R.drawable.ic_round_focus_24),
                contentDescription = "",
                tint = MaterialTheme.colors.primary
            )
        }

        DropdownMenu(
            modifier = Modifier
                .wrapContentWidth()
                .wrapContentHeight()
                .padding(vertical = 0.dp)
                .align(Alignment.Bottom),
            expanded = expandState.value,
            onDismissRequest = {
                expandState.value = false
            },
            offset = DpOffset(64.dp, 0.dp),
        ) {
            MenuItems.Rename(
                state = expandState,
                callback = {
                    showGetStrDialog(context, RStr.stub("输入专题名"), subject.name) { newSubjectName ->
                        // 更新数据库信息
                        if (newSubjectName != "" && newSubjectName != subject.name) {
                            val renamedSubject: WorkSpaceModel.SubjectMetaData =
                                WorkSpaceModel.SubjectMetaData(
                                    uid = subject.uid,
                                    name = newSubjectName,
                                    color = subject.color
                                )
                            viewModel.modSubject(subject, renamedSubject)
                        }
                    }
                }
            )
            MenuItems.Delete(
                state = expandState,
                callback = {
                    showConfirmDialog(context, "确认要删除专题 ${subject.name} 吗", "删除后将专题无法找回") {
                        viewModel.delSubject(subject)
                    }
                }
            )
            MenuItems.Item(
                state = expandState,
                icon = Icons.Rounded.Add,
                text = RStr.stub("添加标签"),
                callback = {
                    showGetStrDialog(context, RStr.stub("输入标签名")){ tagName ->

                        viewModel.addTag2Subject(tagName, subject.uid)
                    }
                }
            )
            if(belongedTag != ""){
                MenuItems.Item(
                    state = expandState,
                    icon = Icons.Rounded.Close,
                    text = RStr.stub("从该标签中移除"),
                    callback = {
                        showConfirmDialog(context, "确认要移除专题 ${subject.name} 与标签 $belongedTag 的关联吗", "专题并不会被删除"){
                            viewModel.unlinkTagFromSubject(subject, belongedTag)
                        }
                    }
                )
            }
        }

    }
}

@OptIn(ExperimentalAnimationApi::class, ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
@Composable
private fun MainList(viewModel: MainActivityContentViewModel){
    val viewState by viewModel.viewState.collectAsState()
    val context = LocalContext.current
    viewState.fSubjectMetaData?.let{ metaData ->
        Column(Modifier.fillMaxSize()) {
            // 标题栏
//            Row(
//                modifier = Modifier
//                    .align(Alignment.CenterHorizontally)
//                    .padding(8.dp)
//            ) {
            Box(
              modifier = Modifier
                  .fillMaxWidth()
                  .clickable {
                      viewModel.highLightCurrentSubject()
                  }
                  .padding(8.dp)
            ) {
                // 标题名称
                Text(
                    text = metaData.name,
                    fontWeight = FontWeight.Bold,
                    fontSize = 24.sp,
                    modifier = Modifier
                        .align(Alignment.Center)

                )
            }

            // 标签列表
            HorizontalTagList(tagList = viewModel.getTagsOfFocusedSubject()){
                viewModel.highLightTag(it)
            }

            AnimatedVisibility(viewState.fSubjectPdf.isNotEmpty()){
                HorizontalPdfList(list = viewState.fSubjectPdf, onItemClick = {
                    context.startPdfActivity(PdfQuery(metaData,it.first))
                },
                menu = { state,pair->
                    MenuItems.Item(
                        state = state,
                        icon = Icons.Rounded.Send,
                        text = RStr.stub("用外部应用打开")
                    ) {
                        context.openPdfExternal(PdfQuery(metaData,pair.first))
                    }
                    MenuItems.Delete(state = state) {
                        showConfirmDialog(context,"确定删除吗？",""){
                            viewModel.onAction(MainActivityContentViewModel.Action.DeletePdf(pair.first))
                        }
                    }
                })
            }


            // 若笔记没有章节，则提示内容
            if(viewState.fSubjectSectionList.isNullOrEmpty()){
                Text(
                    text = "暂无内容  点击右下角加号添加章节",
                    fontWeight = FontWeight.W200,
                    fontSize = 12.sp,
                    fontStyle = FontStyle.Italic,
                    modifier = Modifier.padding(32.dp)
                )
            }
            // 章节列表
            viewState.fSubjectSectionList.let{ list->
                LazyColumn(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(8.dp)
                ){
                    items(list){

                        val expandState = remember {
                            mutableStateOf(false)
                        }

                        Row(verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier.combinedClickable(
                                onClick = {
                                    context.startSectionActivity(
                                        SectionQuery(metaData, it)
                                    )
                                },
                            onLongClick = {
                                expandState.value = true
                            }
                        )) {
                            Icon(imageVector = ImageVector.vectorResource(id = R.drawable.ic_round_section_24), contentDescription = "")
                            Text(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .padding(8.dp),
                                text = it.name,
                                fontSize = 18.sp,
                                fontWeight = FontWeight.SemiBold
                            )

                            DropdownMenu(
                                modifier = Modifier
                                    .wrapContentWidth()
                                    .wrapContentHeight()
                                    .padding(vertical = 0.dp)
                                    .align(Alignment.Bottom),
                                expanded = expandState.value,
                                onDismissRequest = {
                                    expandState.value = false
                                },
                                offset = DpOffset(128.dp, 0.dp),
                            ) {
                                MenuItems.Rename(
                                    state = expandState,
                                    callback = {
                                        showGetStrDialog(context, "输入新章节名", it.name) { newSectionName ->
                                            // 更新数据库信息
                                            if (newSectionName != "" && newSectionName != it.name){
                                                val renamedSection: SubjectModel.SectionMetaData =
                                                    SubjectModel.SectionMetaData(
                                                        uid = it.uid,
                                                        name = newSectionName
                                                    )
                                                viewModel.modSection(it, renamedSection)
                                            }
                                        }
                                    }
                                )
                                MenuItems.Item(
                                    state = expandState,
                                    icon = Icons.Rounded.Place,
                                    text = RStr.stub("获取请求")
                                ) {
                                    showGetStrDialog(context,"MetaData",
                                        gson.toJson(SectionQuery(metaData, it))
                                    ){  str ->
                                        (context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).let{
                                            it.setPrimaryClip(ClipData.newPlainText("SectionQuery",str))
                                        }
                                    }
                                }
                                MenuItems.Delete(
                                    state = expandState,
                                    callback = {
                                        showConfirmDialog(context, "确认要删除章节 ${it.name} 吗", "删除后将无法找回") {
                                            viewModel.delSection(it)
                                        }
                                    }
                                )
                            }
                        }
                    }
                }
            }
        }
    } ?: run{
        Box(
            modifier = Modifier
                .fillMaxSize()
                .clickable {
                    viewModel.openDrawer()
                },
            contentAlignment = Alignment.Center
        ){
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Icon(imageVector = ImageVector.vectorResource(id = R.drawable.ic_launcher_foreground), contentDescription = "")
                Text(
                    text = "从侧栏中选择专题",
                    fontSize = 18.sp
                )
            }
        }
    }
}

@Composable
fun HorizontalTagList(tagList:List<String>,onTagClick:(String)->Unit = {}){
    HorizontalList(
        list = tagList,
        item = {
            Button(
                modifier = Modifier
                    .height(36.dp)
                    .padding(4.dp, 0.dp)
                    .shadow(elevation = 4.dp, shape = RoundedCornerShape(18.dp)),
                onClick = { onTagClick(it) }
            ) { Text(text = it, fontSize = 12.sp,) }
        },
        title = {
            Text(text = "${RStr.from(R.string.tag)}：", fontSize = 15.sp)
        },
        emptyContent = {
            Text(
                text = "暂无标签",
                fontSize = 12.sp,
                modifier = Modifier
                    .padding(6.dp, 3.dp)
            )
        }
    )
}